let path = require('path')
let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html
let MiniCssExtractPlugin = require('mini-css-extract-plugin') // webpack4 抽离css插件 如果想要多个 就多new几个
let OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
let UglifyJsPlugin = require('uglifyjs-webpack-plugin')
let webpack = require('webpack')
module.exports = {
  optimization: { // 优化项
    minimizer:[
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        sourceMap: true
      }),
      new OptimizeCssAssetsWebpackPlugin()
    ]
  },
  devServer: { // 开发服务器的配置
    port: 3000, // 端口号
    progress: true, // 进度条
    contentBase: './build' // 这个文件夹作为静态目录
  },
  mode: 'development', // 模式 默认两种 production development
  entry: './src/index.js', // 入口
  output: {
    filename: 'bundle.[hash:8].js', // 打包后的文件名
    path: path.resolve(__dirname, 'build'), // 路径必须是一个绝对路径
  },
  module: { // 模块
    rules: [ // 规则  css-loader 主要解析 @import 这种语法
      // style-loader 是把css 插入到head的标签中 
      // loader 的特点  单一
      // 用法  字符串 只用一个loader
      // 多个loader 需要[] ['style-loader', 'css-loader']
      // loader的顺序  默认从右向左执行
      // loader 还可以写成对象 方式 [{}] 好处可以传参数
      // 安装eslint eslint-loader
      // {
      //   test: /.js$/,
      //   use: {
      //     loader: 'eslint-loader',
      //     options: {
      //       enforce: 'pre' // 在之前执行 
      //     }
      //   }
      // },
      // 如果要暴露给全局的window  
      // 要用到expose-loader 暴露全局的loader 内联的loader 

      // 在每个模块中注入 window.$  需要用到 webpack插件

      // {
      //   test: require.resolve('jquery'),
      //   use: 'expose-loader?$'
      // },
      // babel-loader 核心模块@babel/core  转化成es5@babel/preset-env  
      // 一些高级js语法还需要有其他 插件 class @babel/plugin-proposal-class-properties
      // 装饰器的话 还要安装 装饰器的插件 @babel/plugin-proposal-decorators 
      // 一些像 *gennerater函数 需要插件 @babel/plugin-transform-runtime  @babel/runtime
      // 实例上的方法都不回帮你去解析 'aaa'.includes('a')  es7的方法  要解析的话 可以用@babel/polyfill
      {
        test: /.js$/,
        use: {
          loader: 'babel-loader',
          options: { // 用babel-loader 需要把es6->es5
            presets: [
              '@babel/preset-env'
            ],
            plugins: [
              ["@babel/plugin-proposal-decorators", { "legacy": true }],
              ["@babel/plugin-proposal-class-properties", { "loose" : true }],
              "@babel/plugin-transform-runtime"
            ]
          }
        },
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/
      },
      {
        // 可以处理less文件  sass  stylus
        test: /\.css$/, 
        use: [
          MiniCssExtractPlugin.loader, 
          'css-loader',
          'postcss-loader' // 先处理postcss
        ]
      },
      {
        test: /\.less$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'less-loader' // less-loader 调用less 来解析
        ] 
      }
    ]
  },
  externals: { // 这个做就是说忽略这个 jQuery 不打包进去
    'jquery': '$'
  },
  plugins: [ // 插件
    new HtmlWebpackPlugin({
      template: './src/index.html', // 指定模板
      filename: 'index.html', // 打包后文件
      hash: true // 生成hash戳
    }),
    new MiniCssExtractPlugin({
      filename: 'main.css'
    }),
    new webpack.ProvidePlugin({  // 在每个模块中 都注入$  但不是window.$
      $: 'jquery'
    })
  ]
}